 var appUrl = "#ex_appUrl";
 var commonUrl = "#ex_commonUrl";

//用户登录成功的广播事件
var cmfEvent_LoginSuccessEvent = "cmfEvent_LoginSuccessEvent";
//用户登出成功后的广播事件
var cmfEvent_LogoutSuccessEvent = "cmfEvent_LogoutSuccessEvent";
//页面数据主动刷新事件
var cmfEvent_RefreshPageDataEvent = "cmfEvent_RefreshPageDataEvent";
//当前页面即将呈现的事件
var cmfEvent_CurrentPageWillAppear = "cmfEvent_CurrentPageWillAppear";
//当前页面呈现完成的事件
var cmfEvent_CurrentPageDidAppear = "cmfEvent_CurrentPageDidAppear";
//当前页面即将消失的事件
var cmfEvent_CurrentPageWillDisappear = "cmfEvent_CurrentPageWillDisappear";
//当前页面消失完成，页面即将释放的事件
var cmfEvent_CurrentPageWillUnload = "cmfEvent_CurrentPageWillUnload";
//安卓物理返回键事件
var cmfEvent_AndroidBack = "cmfEvent_AndroidBack";
//原生键盘数据输入事件
var cmfEvent_KeyboardInputing = "cmfEvent_KeyboardInputing";
//原生键盘删除字符事件
var cmfEvent_KeyboardDeleteChar = "cmfEvent_KeyboardDeleteChar";
// 原生键盘点击确定按钮事件
var cmfEvent_KeyboardComfirmButtonClick = "cmfEvent_KeyboardComfirmButtonClick";
//原生网络状态监测事件
var cmfEvent_NetworkDetect = "cmfEvent_NetworkDetect";
//进程关闭监测事件
var cmfEvent_ProcessWillShutDown = "cmfEvent_ProcessWillShutDown";

var handler = function(event){
  event.preventDefault();
};

var cmf = cmf || {};

cmf.route = cmf.route || {}; //容错cumroutejs

    //用于供PC端调试的开关
cmf.route.isDebug = false;
//用户账号操作类，包括登入登出数据缓存、用户信息查询等
cmf.UserUtil = cmf.UserUtil || {

  /**
   *
   *  获取登录态下的cmfUserId
   *
   */
  getCmfUserId: function() {
    var userInfoObj = this.getLoginUserInfo();
    if (userInfoObj != null) {
      return userInfoObj.cmfUserId;
    }
    return null;

  },

  getCmfLoginId: function() {
    if (cmf.route.isDebug) {
      var loginId = sessionStorage.getItem("loginId");
      return loginId;
    }

    var loginInfo = this.getCmfLoginInfo();

    if (loginInfo != null) {
      loginId = loginInfo.loginId;
    }

    return loginId;
  },

  getCmfLoginInfo: function() {
    if (cmf.route.isDebug) {
      var info = sessionStorage.getItem('loginInfo');
      if (info != null && info != undefined) {
        return JSON.parse(info);
      }
    }

    var param = {};
    param["funcNo"] = "80005";
    var loginId = null;
    var result = callMessageNative(param);
    var loginInfo = this.parseLoginInfoResult(result);
    if (typeof loginInfo === 'string') {
      loginInfo = JSON.parse(loginInfo);
    }

    if (loginInfo != null) {
      //console.log("getCmfLoginInfo: " + loginInfo);
      sessionStorage.setItem("loginInfo", loginInfo);
      sessionStorage.setItem("loginId", loginInfo.loginId);
      sessionStorage.setItem("loginUserInfo", loginInfo.loginUserInfo);
    }
    return loginInfo;
  },

  /**
   *
   *  获取登录缓存的信息
   *
   */
  getLoginUserInfo: function() {
    var infoStr;
    if (cmf.route.isDebug) {
      infoStr = sessionStorage.getItem('loginUserInfo');
      if (infoStr != null && infoStr != undefined) {
        return JSON.parse(infoStr);
      }
      return null;
    }

    var loginInfo = this.getCmfLoginInfo();

    if (loginInfo != null)
      infoStr = loginInfo.loginUserInfo;

    if (infoStr != null && infoStr != undefined) {
      return infoStr;
    } else {
      return null;
    }
  },

  /**
   *
   *  获取手机号、密码等登录账号的缓存信息
   *
   */
  getLoginAccountInfo: function() {
    var infoStr;
    if (cmf.route.isDebug) {
      var loginInfo = sessionStorage.getItem('loginInfo') ? JSON.parse(sessionStorage.getItem('loginInfo')) : null;

      if (loginInfo != null && loginInfo != undefined) {
        infoStr = loginInfo.AccountInfo ? loginInfo.AccountInfo : null;
        return infoStr;
      }

      return null;
    }

    var loginInfo = this.getCmfLoginInfo();

    if (loginInfo != null)
      infoStr = loginInfo.AccountInfo;
    if (infoStr != null && infoStr != undefined) {
      return infoStr;
    } else {
      return null;
    }
  },
  /**
   *  获取用户类型
   *
   */
  getLoginUserType: function() {
    if (cmf.route.isDebug) {
      var loginUserInfo = sessionStorage.getItem('loginUserInfo');
      if (loginUserInfo != null && loginUserInfo != undefined) {
        return JSON.parse(loginUserInfo).userType;
      }
    }
    var loginInfo = this.getCmfLoginInfo();
    try {
      return loginInfo.loginUserInfo.userType;
    } catch (e) {
      return null;
    }
  },
  /**
   *  获取用户头像信息
   *
   */
  getUserImageData: function() {

  },
  /**
   *  获取保存在native中的手势密码信息
   *
   */
  getH5LockFromNative: function(key) {
    if (cmf.route.isDebug)
      try {
        return JSON.parse(sessionStorage.getItem(key));
      } catch (e) {
        return null;
      }
    try {
      var param = {};
      param["funcNo"] = "50043";
      param["key"] = key;
      var result = callMessageNative(param);
      if (result.results) {
        var loackData;
        if (typeof result.results[0].value === 'object') {
          loackData = result.results[0].value;
        } else if (typeof result.results[0].value === 'string') {
          loackData = JSON.parse(result.results[0].value);
        }
        return {
          result: true,
          data: loackData
        };
      } else {
        return {
          result: false,
          error: result.error_info
        };
      }
    } catch (e) {
      console.log(e)
    }
  },
  //存数据到内存
 saveMemoryData:function(key,value){
      var param = {};
         param["funcNo"] = "50040";
         param["key"] = key;
         param["value"]=value;
         var result = callMessageNative(param);
 },
    //从内存取数据
 getMemoryData:function(key){
     var param={};
      param["funcNo"]="50041";
      param["key"]=key;
      var result = callMessageNative(param);
      return result;

 },
  //查询是否开启消息通知
  getIsOpenMessage:function(){
      var param={};
      param["funcNo"]="81021";
      var result =callMessageNative(param);
      //返回值isOpen  Y :已开启，N :未开启
      if(result.results[0]){
          return result.results[0]
      }else{
          return {};
      }
  },
  //设置开启消息通知
  openMesssageStatus:function(){
      var param={};
      param["funcNo"]="81022";
      var result =callMessageNative(param);
  },
  //检查登录状态专用
  checkLoginStatus: function() {
    if (cmf.route.isDebug) {
      var loginId = sessionStorage.getItem("loginId");

      if (loginId)
        return true;
      else return false;
    }

    var loginInfo = this.getCmfLoginInfo();

    if (loginInfo != null)
      loginId = loginInfo.loginId;

    if (loginId != null && loginId != undefined && loginId.length > 0) {
      return true;
    } else return false;
  },

  //检查手势密码
  checkH5LockStatus: function() {
    var resultObj = this.getH5LockFromNative('lock');
    if (resultObj && resultObj.result && resultObj.data && resultObj.data.hasLock) {
      return true;
    } else {
      return false;
    }
  },

  parseLoginInfoResult: function(result) {
    // console.log(result);
    // var str = JSON.stringify(result);
    // alert("parseLoginInfoResult:"+str);
    if (result.error_no == 0) {
      if (result.results == null) {
        return null;
      };

      var arrInfo = result.results[0];

      if (arrInfo != null && arrInfo != undefined) {
        var loginInfo = arrInfo.loginInfo;

        if (loginInfo) {
          return loginInfo;
        } else return null;
      } else return null;
    }

    return null
  },

  /**
   *  保存用户信息及登录号(session)
   *
   */
  saveUserInfoAndLoginId: function(data) {
    var loginInfo = this.getCmfLoginInfo();
    loginInfo = loginInfo || {};

    loginInfo.loginId = data.loginId;
    loginInfo.loginUserInfo = data.loginUserInfo;

    this.saveUserInfoToNative(loginInfo);
  },

  /**
   *  保存用户手机号、账号密码等信息
   *
   */
  saveUserAccountInfo: function(data) {
    var loginInfo = this.getCmfLoginInfo();
    loginInfo = loginInfo || {};

    loginInfo.AccountInfo = data;

    this.saveUserInfoToNative(loginInfo);
  },

  /**
   *  保存手势密码相关信息到NATIVE中
   *
   */
  saveH5LockToNative: function(key, data) {
    if (cmf.route.isDebug) {
      var lockData = {};
      lockData.result = true;
      lockData.data = data;
      sessionStorage.setItem(key, JSON.stringify(lockData));
      return;
    }
    try {
      var param = {};
      param["funcNo"] = "50042";
      param["key"] = key;
      param["value"] = JSON.stringify(data);
      var result = callMessageNative(param);
      if (result.error_no == 0)
        return true;
      else
        return result.error_info;

    } catch (e) {
      console.log(e)
    }

  },

  saveUserInfoToNative: function(data) {
    var userInfo = JSON.stringify(data.loginUserInfo);
    sessionStorage.setItem("loginId", data.loginId);
    sessionStorage.setItem("loginUserInfo", userInfo);
    sessionStorage.setItem("loginInfo", JSON.stringify(data));
    if (cmf.route.isDebug) {
      return;
    }
    try {
      var param = {};
      param["funcNo"] = "80004";
      param["loginId"] = data.loginId;
      param["loginUserInfo"] = userInfo;
      param["loginInfo"] = data;
      var result = callMessageNative(param);
    } catch (e) {
      console.log(e)
    }
  },
  savePhoneNo: function(data) {
    try {
      var param = {};
      param['funcNo'] = '50042';
      param['key'] = 'phoneNo';
      param['value'] = data.phoneNo;
      param['time'] = 0;
      var result = callMessageNative(param);
    } catch (e) {

    }

  },
  getPhoneNo: function(key) {
    try {
      var param = {};
      param['funcNo'] = '50043';
      param['key'] = key;
      var result = callMessageNative(param);
      if (result.results[0].value !== '')
        return JSON.parse(result.results[0].value);
      else
        return null;
    } catch (e) {

    }

  },

  /**
   *  退出登录，清除用户信息
   */
  loginOut: function() {
    try {
      if (cmf.route.isDebug) {
        sessionStorage.setItem("loginId", "");
        sessionStorage.setItem("loginUserInfo", JSON.stringify("{'cmfUserId':'','crmCustNo':'','custno':'','idNo':'','timeStamp':0,'userName':''}"));
        sessionStorage.setItem("loginInfo", null);
        return;
      }
      //TODO: HJ 后续考虑将手势密码的清理也整合一下
      //            var param = {};
      //            param["funcNo"] = "50042";
      //            param["key"] = "lock";
      //            param["value"] = "";
      //            callMessageNative(param);
      //执行登出操作，清空本地缓存并同步各WebView的状态
      var param2 = {};
      param2["funcNo"] = "80006";
      callMessageNative(param2);
    } catch (e) {
      console.log(e)
    }
  },

  //跳转登录页或手势登录页,支持重定向功能
  goNewModuleWithLoginCheck: function(url,data,callBack) {
    data=data || {};
    if (cmf.UserUtil.checkLoginStatus()) {
      if (callBack) {
        callBack(url,data);
      } else {
        cmf.route.goNewModuleWithData(url,data);
      }
    } else {
      if (cmf.UserUtil.checkH5LockStatus()) {
        cmf.route.goNewModuleWithRedirectUrl("../account/loginIndex.html#/lock.html", url,data);
      } else {
        cmf.route.goNewModuleWithRedirectUrl("../account/loginIndex.html", url,data);
      }
    }
  },

    //获取用户等级信息，0：内部员工，1：外部用户
    getCmfUserLevel:function(){
        var accountInfo=this.getLoginAccountInfo();
        if(accountInfo !==null){
            if(accountInfo.userLevel===''){
                return '1';   //默认值
            }else{
                return accountInfo.userLevel;
            }
        }else{
            return '1';   //默认值
        }

    },

    //获取用户职级信息，0：普通员工，1：领导
    getCmfUserRank:function(){
        var accountInfo=this.getLoginAccountInfo();
        if(accountInfo !==null){
            if(accountInfo.userRank===''){
                return '0';  //默认值
            }else{
                return accountInfo.userRank;
            }
        }else{
            return '0';  //默认值
        }

    }
};
//------- cmf.UserUtil end ------------


//原生视图交互工具类
cmf.NativeViewUtil = cmf.NativeViewUtil || {
  callbackFuncArr: {},

  //数据存储器。自动根据PC或者手机设备存储数据。
  storage:{
      get:function(key){
        if(cmf.route.isDebug){
          var value = localStorage.getItem(key);
          if(value){
            return JSON.parse(value);
          }else{
            return null;
          }
        }else{
          try {
            var param = {};
            param['funcNo'] = '50043';
            param['key'] = key;
            var result = callMessageNative(param);
            console.log("get result，key is :"+key);
            console.log(result);
            if (result.results != null && result.results.length > 0 && result.results[0].value)
              return JSON.parse(result.results[0].value);
            else
              return null;
          } catch (e) {
            console.log("取值时发生了一个异常");
            console.log(e);
          }
        }
      },
      set:function(key,value){
        if(cmf.route.isDebug){
          localStorage.setItem(key,JSON.stringify(value));
        }else{
          try {
            var param = {};
            param['funcNo'] = '50042';
            param['key'] = key;
            param['value'] = JSON.stringify(value);
            param['time'] = 0;
            console.log("set data ,key is :"+key);
            console.log(param['value']);
            var result = callMessageNative(param);
          } catch (e) {
            console.log("设置值时发生了一个异常");
            console.log(e);
          }
        }
      }
  },

  /**
   *  查看pdf
   *
   */
  //title  content   type  flag   width   height
  checkPDF: function(url) {
    try {
      var parm = {};
      parm["funcNo"] = "81007";
      parm["url"] = url;
      var result = callMessageNative(parm);
    } catch (e) {
      console.log(e);
    }
  },


  /**
   *  alertview 提示框
   *
   */
  //title  content   type  flag   width   height
  showAlert: function(content, cancelCallback) {
    if(cmf.Util.isObject(content)){
        content=content.resultMsg || '系统错误';
    }
    if (cmf.route.isDebug) {
      console.log(content);
      return;
    }
    try {
      if(content==='logonFailureOut'){
         return;
      }
      if(content==='cmfErrorApp3.0Network'){
          //toast提示 网络繁忙
          this.showToastView('请求失败，请检查网络状态!');
      }else{
          var parm = {};
          parm["funcNo"] = "81006";
          parm["title"] = '';
          parm["message"] = content;
          parm["cancel"] = '我知道了';
          parm["other"] = '';
          // parm["type"] = "0";
          // parm["flag"] = '0';
          // parm["width"] = window.screen.width*0.8;
          //  parm["height"] = window.screen.height*0.8;

          var funcID;
          if (cancelCallback) {
              funcID = "cb_showAlert_" + new Date().getTime();
              this.callbackFuncArr[funcID] = cancelCallback;
              parm["cancelCallback"] = funcID;
          }
          var result = callMessageNative(parm);
      }
    } catch (e) {
      console.log(e);
    }
  },
    
    //  showHeightMoneyCallback
    /**
     *  高端理财提示框
     *
     */
    showHeightMoneyCallback: function(callback,cancelCallback) {
        var parm = {};
        parm["funcNo"] = "81014";
        var funcID;
        
        if (callback) {
            funcID = "cb_showHeightMoneyView_" + new Date().getTime();
            this.callbackFuncArr[funcID] = callback;
            parm["callback"] = funcID;
        }
        
        if (cancelCallback) {
            funcID = "cb_showHeightMoneyView_" + (new Date().getTime() + 5);
            this.callbackFuncArr[funcID] = cancelCallback;
            parm["cancelCallback"] = funcID;
        }
        
        var result = callMessageNative(parm);
    },
    
    
    //  showPayAlertCallback
    /**
     *  支付密码  alertview 提示框
     *
     */
        showPayAlertCallback: function(title, message,bankCard,callback,cancelCallback) {
            var parm = {};
            parm["funcNo"] = "81010";
            parm["title"] = title;
            parm["message"] = message;
            parm["bankCard"] = bankCard;
            var funcID;
            
            if (callback) {
                funcID = "cb_showPayAlertView_" + new Date().getTime();
                this.callbackFuncArr[funcID] = callback;
                parm["callback"] = funcID;
            }
            
            if (cancelCallback) {
                funcID = "cb_showPayAlertView_" + (new Date().getTime() + 5);
                this.callbackFuncArr[funcID] = cancelCallback;
                parm["cancelCallback"] = funcID;
            }
            
            var result = callMessageNative(parm);
        },
    /*
     *   隐藏支付密码提示框（原生）
     */
        hidePayAlert:function(){
            var parm = {};
            parm["funcNo"]= "81011";
            var result = callMessageNative(parm);
        },
    /**
     *  两个按钮的  alertview 提示框
     *
     */
  showAlertViewWithCallback: function(title, message, other, cancel, callback, cancelCallback) {
    var parm = {};
    parm["funcNo"] = "82006";
    parm["title"] = title;
    parm["message"] = message;
    parm["cancel"] = cancel;
    parm["other"] = other;
    var funcID;

    if (callback) {
      funcID = "cb_showAlertView_" + new Date().getTime();
      this.callbackFuncArr[funcID] = callback;
      parm["callback"] = funcID;
    }

    if (cancelCallback) {
      funcID = "ccb_showAlertView_" + (new Date().getTime() + 5);
      this.callbackFuncArr[funcID] = cancelCallback;
      parm["cancelCallback"] = funcID;
    }

    var result = callMessageNative(parm);
  },

  showToastView: function(content) {
    if (cmf.route.isDebug) {
      console.log(content);
      return;
    }
    try {
      if(content==='logonFailureOut'){
          return;
      }
      var parm = {};
      parm["funcNo"] = "50106";
      parm["content"] = content;

      var result = callMessageNative(parm);
    } catch (e) {
      if (cmf.route.isDebug)
        console.log(e);
    }
  },

  showLoadingView: function(isShow) {
    this.loaddingGif({
      hidden: !isShow
    });
  },

  /**
   *  loadding gif
   *
   */
  loaddingGif: function(parm) {
    if (cmf.route.isDebug) {
    console.log('原生加载动画显示' + (!parm.hidden));
    if (!parm.hidden) {
      console.time('请求时长');
    } else if (parm.hidden) {
      console.timeEnd('请求时长');
    }
      return;
    }
    try {
      parm["funcNo"] = "82008";
      parm["url"] = window.location.href;
      var result = callMessageNative(parm);
    } catch (e) {
      console.log(e);
    }
  },

  /**
   *  分享
   *
   */
  shareContent: function(parm) {
    try {

          if(window.iBrowser.android){
              parm["funcNo"] = "50230";

           }else{
              parm["funcNo"] = "81018";
            }


      parm["shareTypeList"] = "22,23";
      if (parm.title == null || parm.title == "" || parm.title == undefined) {
        parm["title"] = "给基友们推荐好基!";
      }
      //parm["link"] = "https://wx.cmfchina.com/WeixinService/fund/queryFundById.xhtml?fundId=217004";
      // param["content"] = "50230";
      parm["description"] = "";
      parm["imgUrl"] = "";
      var result = callMessageNative(parm);
    } catch (e) {
      console.log(e);
    }
  },
  /**
   *  选择照片
   *
   */
  getPhoto: function(pageId) {
    try {
      var param = {};
      var loginId = cmf.UserUtil.getCmfLoginId();
      param["funcNo"] = "50273";
      param["moduleName"] = pageId;
      param["serverAddr"] = "http://59.37.11.117/commonweb/account/headPhotoUpload";
      param["fileName"] = "myPhoto";
      param["paramExt"] = JSON.stringify({
        loginId: loginId
      });
      var result = callMessageNative(param);
    } catch (e) {
      console.log(e);
    }
  },
  /*
   去appStore评分功能
   */
  goAppStore: function() {
    try {
      var param = {};
      param["funcNo"] = "81001";
      var result = callMessageNative(param);
    } catch (e) {
      console.log(e);
    }
  },

  /*
   功能介绍
   */
  goIntroduce: function() {
    try {
      var param = {};
      param["funcNo"] = "81002";
      var result = callMessageNative(param);
    } catch (e) {
      console.log(e);
    }
  },

  /**
   *  H5调用功能号50210 弹出原生键盘
   *
   */
  keyboardUpForNative: function(pageId, eleId, type) {
    if (cmf.route.isDebug) {
      return;
    }
    try {
      var param = {};
      param["funcNo"] = "50210";
      param["keyboardType"] = type;
      param["pageId"] = pageId;
      param["eleId"] = eleId;
      param["moduleName"] = pageId;
      var result = callMessageNative(param);
    } catch (e) {
      console.log(e)
    }
  },

  /**
   *  H5调用功能号50211 隐藏原生键盘
   *
   */
  keyboardDownForNative: function(mode) {
    if (cmf.route.isDebug) {
      return;
    }
    try {
      var param = {};
      param["funcNo"] = "50211";
      param["mode"] = mode;
      var result = callMessageNative(param);
    } catch (e) {
      console.log(e)
    }
  },
  /**
   *  H5调用原生隐藏tabbar，模块内跳转
   *
   */
  setTabbarHiddenInModel: function(hidden) {
    // var param = {};
    //  param["funcNo"] = "81003";
    // param["hidden"] = hidden;
    // var result = callMessageNative(param);
  },
  setTabbarHidden: function(hidden) {
    //  var param = {};
    //  param["funcNo"] = "81004";
    //  param["hidden"] = hidden;
    //  var result = callMessageNative(param);
  },

  /**
   *  H5控制Native导航条，是否支持右滑返回
   *
   */
  setCanDragBack: function(canDragBack) {
    //仅在IOS上使用
    if (window.iBrowser.ios) {
      var param = {};
      param["funcNo"] = "80017";
      param["canDragBack"] = canDragBack;
      var result = callMessageNative(param);
    }
  },

  /**
   * 调用RSA原生加密接口，主要用于登录密码和支付密码的加密
   */
  encryptRSA: function(password) {
    if (!password) {
      return '';
    }
    if (cmf.route.isDebug)
      return password;
    var param = {};
    param["funcNo"] = "81005";
    param["password"] = password;
    var result = callMessageNative(param);
    if (result.error_no == 0) {
      if (result.results == null) {
        return null;
      };
      var arrInfo = result.results[0];

      if (arrInfo != null && arrInfo != undefined) {
        var encryptPassWord = arrInfo.encryptPassWord;

        if (encryptPassWord) {
          return encryptPassWord;
        } else return null;
      } else return null;
    }
    return null;
  },

  /**
   * 拨打电话
   */
  dail: function(telNumber) {
    if (!telNumber) {
      return '';
    }
    if (cmf.route.isDebug)
      return '';

    try {
      var param = {};
      param["funcNo"] = "50220";
      param["telNo"] = telNumber;
      param["callType"] = '1';
      var result = callMessageNative(param);
    } catch (e) {
      console.log(e)
    }
  },

  /**
   * 获取设备基本信息
   */
  getDeviceInfo: function() {
    if (cmf.route.isDebug)
      return null;

    try {
      var param = {};
      param["funcNo"] = "50001";
      var result = callMessageNative(param);
      return result;
    } catch (e) {
      console.log(e)
    }
  },

  /**
   * 获取手机唯一标识
   */
  getDeviceId: function() {
    if (cmf.route.isDebug)
      return null;

    try {
      var param = {};
      param["funcNo"] = "50022";
      var result = callMessageNative(param);
      return result;
    } catch (e) {
      console.log(e)
    }
  },
  /*
  * 检测网络状态
  */
  checkNetWorkStatus:function(){
    if(cmf.route.isDebug){
      return null;
    }
    try{
      var param = {};
      param['funcNo'] = '81012';
      var result = callMessageNative(param);
      return result;
    }catch(e){
      console.log(e);
    }
  },
  /*
  *显示遮罩（状态栏和tab栏遮罩） 
  * alpha 遮罩透明度
  */
  showBackground:function(alpha){
    console.log("showBackground():调用原生显示蒙层方法，alpha:"+alpha);
    if(cmf.route.isDebug){
      return null;
    }
    var defaultAlpha = 0.7;
    if(alpha == undefined || alpha == null){
      alpha = defaultAlpha;
    }
    try{
      var param = {};
      param['funcNo'] = '81013';
      param['hidden'] = false;
      param['alpha'] = ""+alpha;
      var result = callMessageNative(param);
    }catch(e){
      console.log(e);
    }
  },
  // showBackground:function(){
  //    this.showHeightMoneyCallback();  //原生方式
  // },
  /*
  *隐藏遮罩（状态栏和tab栏遮罩）
  */
  hideBackground:function(){
    console.log("hideBackground():调用原生隐藏蒙层方法");
    if(cmf.route.isDebug){
      return null;
    }
    try{
      var param = {};
      param['funcNo'] = '81013';
      param['hidden'] = true;
      param['alpha'] = '';
      var result = callMessageNative(param);
    }catch(e){
      console.log(e);
    }
  },

  /*
  * 获取app版本号
  */
  getAppVersion:function(){
    if(cmf.route.isDebug){
      return;
    }
    try{
      var param = {};
      param["funcNo"] = '50010';
      var result = callMessageNative(param);
      if(result != null){
            if(result.results[0] != null && result.results[0] != undefined){
                return result.results[0].version;
            }
      }
      return null;
    }catch(e){
      console.log(e);
    }
  },
  /*
  * 原生评价框
  */
  showNativeJudge:function(){
    if(cmf.route.isDebug){
      return;
    }
    try{
      var param = {};
      param["funcNo"] = '81019';
      var result = callMessageNative(param);
      return result;
    }catch(e){
      console.log(e);
    }
  },
    /*
     * 调用原生拍照识别银行卡
     */
    photoRecognitionBank:function(func, completeFunc){
        if(cmf.route.isDebug){
            return;
        }
        var param={};
        param['funcNo']='81023';

        var funcID = 'callBackForNative' + (new Date().getTime());
        this.callbackFuncArr[funcID] = func;
        param["callBack"] = funcID;

        funcID = 'completeCallBack' + (new Date().getTime() + 5);
        this.callbackFuncArr[funcID] = completeFunc;
        param['completeCallBack'] = funcID;

        var result = callMessageNative(param);
    },
    /*
     * 调用原生拍照识别身份证
     */
    photoRecognitionID:function(func){
        if(cmf.route.isDebug){
            return;
        }
        var param={};
        param['funcNo']='81024';
        param['isFont']='true';
        param['callBack']='callBackForNative';
        this.callbackFuncArr['callBackForNative']=func;
        var result = callMessageNative(param);
    }
};


//通用工具类
cmf.Util = cmf.Util || {
  isNullString: function(str) {
    if (str != null && str != '' && undefined != str && "null" != str && str.length > 0 && "undefined" != str)
      return false;

    return true;
  },
  //获取正确的url
  getNewUrl: function(str, parme) {
    var oUrl = str.split('#');
    if (oUrl.length <= 1) {
      return str;
    } else {
      oUrl[1] = parme;
      return oUrl[0] + '#' + oUrl[1];
    }
  },

  /**
   *  查询url上附带的参数
   *  如：url = http://www.cmfchina.com?fundId=000588
   在该页面调用getParamterFromUrl('fundId') 即可获取出000588
   */
  getParamterFromUrl: function(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    var r = window.location.search.substr(1).match(reg);
    if (r != null)
      return unescape(r[2]);
    return null;
  },

    getParamterFromUrlWithKey: function(url,name) {
        if(this.isNullString(url))
        {
            return null;
        }

        //(?:^|\?|&)courseid=(\d*)(?:&|$)
        var reg = new RegExp("(^|\\?|&)" + name + "=([^&]*)(&|$)", "i");
        var r = url.match(reg);
        if (r != null)
            return unescape(r[2]);
        return null;
    },

  //是否含有数字
  hasNumber: function(val) {
    return /^(\D*\d+\D*)+$/.test(val);
  },
  //是否含有字母
  hasLetter: function(val) {
    return /^([^a-zA-Z]*[a-zA-Z]+[^a-zA-Z]*)+$/.test(val);
  },
  //手机格式验证
  mobileRex: function(val) {
    return /^1[3-8]\d{9}$/.test(val);
  },
  //验证码格式验证
  verifyCodeRex: function(val) {
    return /^\d{6}$/.test(val);
  },
  //登录密码格式验证
  loginPassRex: function(val) {
    return /^[0-9]{6,8}$/.test(val);
  },
  //是否含有半角特殊字符
  hasBanJiaoSpacialChar: function(val) {
    return /^([^\~\`\!\@\#\$\%\^\&\*\(\)\_\-\+\=\{\[\}\]\|\\\:\;\"\'\<\,\>\.\?\/]*[\~\`\!\@\#\$\%\^\&\*\(\)\_\-\+\=\{\[\}\]\|\\\:\;\"\'\<\,\>\.\?\/]+[^\~\`\!\@\#\$\%\^\&\*\(\)\_\-\+\=\{\[\}\]\|\\\:\;\"\'\<\,\>\.\?\/]*)+$/.test(val);
  },
  //是否含有小写字母
  hasLowerLetter: function(val) {
    return /^([^a-z]*[a-z]+[^a-z]*)+$/.test(val);
  },
  //是否含有大写字母
  hasUpperLetter: function(val) {
    return /^([^A-Z]*[A-Z]+[^A-Z]*)+$/.test(val);
  },
  payPassRex: function(val) {
    //var booVal = new Boolean(val);
    if (val) {
      val = val.trim();
      if (val.length < 6 || val.length > 16) {
        return false;
      }
      if (this.hasNumber(val) && this.hasLetter(val) && this.hasBanJiaoSpacialChar(val)) {
        return true;
      }
      if ((this.hasNumber(val) && this.hasLetter(val)) || //有数字和字母
        (this.hasNumber(val) && this.hasBanJiaoSpacialChar(val)) || //有数字和半角特殊字符
        (this.hasLetter(val) && this.hasBanJiaoSpacialChar(val)) || //有字母和半角特殊字符
        (this.hasLowerLetter(val) && this.hasUpperLetter(val))) { //有小写字符和大写字符
        return true;
      }
    }
    return false;
  },
  //校验身份证
  isIdCardNumber4ZSJJ: function(_val) {
    var citys = {
      11: "北京",
      12: "天津",
      13: "河北",
      14: "山西",
      15: "内蒙古",
      21: "辽宁",
      22: "吉林",
      23: "黑龙江",
      31: "上海",
      32: "江苏",
      33: "浙江",
      34: "安徽",
      35: "福建",
      36: "江西",
      37: "山东",
      41: "河南",
      42: "湖北",
      43: "湖南",
      44: "广东",
      45: "广西",
      46: "海南",
      50: "重庆",
      51: "四川",
      52: "贵州",
      53: "云南",
      54: "西藏",
      61: "陕西",
      62: "甘肃",
      63: "青海",
      64: "宁夏",
      65: "新疆",
      71: "台湾",
      81: "香港",
      82: "澳门",
      91: "国外"
    };
    var iSum = 0;
    var info = "";
    if (!/^\d{17}(\d|x)$/i.test(_val)) {
      return "证件号码填写错误，请重新核对填写";
    }
    _val = _val.replace(/x$/i, "a");
    if (citys[parseInt(_val.substr(0, 2))] == null) {
      return "你的身份证地区非法";
    }
    var sBirthday = _val.substr(6, 4) + "-" + Number(_val.substr(10, 2)) + "-" + Number(_val.substr(12, 2));
    var d = new Date(sBirthday.replace(/-/g, "/"));
    if (sBirthday != (d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate())) {
      return "身份证上的出生日期非法";
    }
    for (var i = 17; i >= 0; i--) {
      iSum += (Math.pow(2, i) % 11) * parseInt(_val.charAt(17 - i), 11);
    }
    if (iSum % 11 != 1) {
      return "你输入的身份证号非法";
    }
    return true;
  },
  //军官证校验
  checkIdType2: function(val) {
    var idNo = val.trim();
    //判断是否有半角特殊字符
    var hasSpacialChar = /^(((?!\s|。|《|》|、)[\u2E80-\u9FFFa-zA-Z0-9])*([^\u2E80-\u9FFFa-zA-Z0-9]|\s|。|《|》|、)+((?!\s|。|《|》|、)[\u2E80-\u9FFFa-zA-Z0-9])*)+$/;
    if (!hasSpacialChar.test(idNo)) {
      return true;
    }
    return false;
  },
  //除了身份证，军官证的证件号码验证
  checkIdNo: function(val) {
    if ((/^[a-zA-Z0-9]{1,}$/.test(val))) {
      return true;
    }
    return false;
  },

  /**
   * 设置99click中各页面的步骤名与标题
   */
  setStatisticsInfo: function(topic, title) {
    //        alert('fundbuy_step1 oa_webview: ' + oa_webview);
    //        alert(oa_AppTrack);

      if(cmf.Config.isUser99ClickLog)
      {
          if (!this.isNullString(topic)) {
              window._oatopic = topic;
          }

          if (!this.isNullString(title)) {
              window._oatitle = title;
          }

          var userId = cmf.UserUtil.getCmfUserId();
          var cusParam;

          //增加用户ID
          if (!this.isNullString(userId))
          {
              cusParam = "&ozsru=" + userId;
          }

          this.setStatisticsCustomInfo(topic,title,cusParam);
      }
  },
  setStatisticsPic:function(topic,title){
      if(cmf.Config.isUser99ClickLog)
      {
          if (!this.isNullString(topic)) {
              window._oatopic = topic;
          }

          if (!this.isNullString(title)) {
              window._oatitle = title;
          }
          // var userId = cmf.UserUtil.getCmfUserId();
          // if (!this.isNullString(userId))
          // {
          //     window._oaprm = '&ozsru'+userId;
          // }
      }
  },
    /**
     * 设置99click中各页面的步骤名、标题、自定义参数
     */
    setStatisticsCustomInfo: function(topic, title, customParam) {
        if(cmf.Config.isUser99ClickLog)
        {
            if (!this.isNullString(topic)) {
                window._oatopic = topic;
            }

            if (!this.isNullString(title)) {
                window._oatitle = title;
            }

            if (!this.isNullString(customParam))
            {
                window._oaprm = customParam;
            }

//            console.log("99click: " + customParam);
            this.countPV();
        }
    },
      /**
     * 设置99click点击事件发送参数
     */
     setStatisticsOzclk:function(oaprm){
         if(cmf.Config.isUser99ClickLog){
          if (oaprm)
            {

                try
                {
                    if (oacode) {
                        oacode. __ozfaj2(oaprm.clickName,'A',oaprm.clickType,'');
//                        window.location.href = window.location.href;
                    }
                }
                catch (e) {
//              console.log("setStatisticsOzclk exception：" + e);
                }

            }
         }
     },
  /**
   * 手动发送PV
   */
  countPV: function() {
      if(cmf.Config.isUser99ClickLog)
      {
          try
          {
              if (oacode) {
                  oacode.ozPageView();
//              alert("countPV");
              }
          }
          catch (e)
          {
//              alert("countPV" + e);
//              console.log("countPV exception：" + e);
          }
      }
  },
  /*
   功能：截取金额  保留两位小数（截取）
   入参：data:  需要格式化的金额
   返回：格式化后的金额
  */
  subDeciem: function(data) {
    data = data == undefined ? '' : data;
    var s_data = parseFloat(data).toString();
    var s_num = s_data.indexOf('.');
    if (s_num < 0) {
      s_data += '.00';
    } else {
      if (s_data.split('.')[1].length > 1) {
        s_data = s_data.substring(0, s_num + 3);
      } else if (s_data.split('.')[1].length === 0) {
        s_data += '00';
      } else if (s_data.split('.')[1].length === 1) {
        s_data += '0';
      }
    }
    return s_data;
  },
  /*
  功能: 校验金额位数限制
  入参:data :最新输入,oldData上一次金额
  返回:校验后的金额
  */
  checkAmtSize: function(data, oldData) {
    var retOBj = {};
    try {
      if (isNaN(data)) {
        retOBj.data = oldData || '';
        retOBj.setData = true;
      }
      if (data.indexOf('.') === -1 && data.length > 10) {
        retOBj.data = oldData || '';
        retOBj.setData = true;
      } else if (data.indexOf('.') !== -1 && data.length > 13) {
        retOBj.data = oldData || '';
        retOBj.setData = true;
      }
      if (data.split('.')[1].length > 2) {
        retOBj.data = oldData || '';
        retOBj.setData = true;
      }
    } catch (e) {}
    return retOBj;
  },
    /*
    * 功能:校验手机号、验证码位数
    * 入参:data 最新输入 oldData: 上一次数值 len:最大支持的长度
    * 返回:校验后的数值结果
    */
    checkCodeSize:function(data,oldData,len){
      var result = {};
      try{
        if(isNaN(data)){
          result.data = oldData;
          result.setData = true;
        }
        if(data.length > len){
          result.data = oldData;
          result.setData = true;
        }
      }catch(e){
        console.log(e);
      }
      return result;
    }
    ,
    /*
     功能: 判断是否为空对象
     入参:obj :需要校验的对象
     返回:是否是空对象
     */
   isEmptyObject:function(obj){
     var name;
       for(name in obj){
           return !1;
       }
       return !0;
   },
  numReal: {
    /*
     是否为整数
    */
    isInteger: function(obj) {
      return Math.floor(obj) === obj;
    },
    /*
     * 将一个浮点数转成整数，返回整数和倍数。如 3.14 >> 314，倍数是 100
     * @param floatNum {number} 小数
     * @return {object}
     *   {times:100, num: 314}
     */
    toInteger: function(floatNum) {
      var ret = {
        times: 1,
        num: 0
      };
      if (this.isInteger(floatNum)) {
        ret.num = floatNum;
        return ret;
      }
      var strfi = floatNum + '';
      var dotPos = strfi.indexOf('.');
      var len = strfi.substr(dotPos + 1).length;
      var times = Math.pow(10, len);
      var intNum = parseInt(floatNum * times + 0.5, 10);
      ret.times = times;
      ret.num = intNum;
      return ret;
    },
    /*
     * 核心方法，实现加减乘除运算，确保不丢失精度
     * 思路：把小数放大为整数（乘），进行算术运算，再缩小为小数（除）
     *
     * @param a {number} 运算数1
     * @param b {number} 运算数2
     * @param digits {number} 精度，保留的小数点数，比如 2, 即保留为两位小数
     * @param op {string} 运算类型，有加减乘除（add/subtract/multiply/divide）
       该方法原网站下方评论说不同小数位的数字计算会有问题  不过我暂时还没测出来  目前结果都是正确的
     *
     */
    operation: function(a, b, digits, op) {
      var o1 = this.toInteger(a);
      var o2 = this.toInteger(b);
      //  var max,result;
      // if (o1.times > o2.times) {
      //  o2.num = o2.num * o1.times / o2.times;
      //  max = o1.times;
      // } else if (o1.times < o2.times) {
      //  o1.num = o1.num * o2.times / o1.times;
      //  max = o2.times;
      // }
      var n1 = o1.num;
      var n2 = o2.num;
      var t1 = o1.times;
      var t2 = o2.times;
      var max = t1 > t2 ? t1 : t2;
      var result = null;
      switch (op) {
        case 'add':
          if (t1 === t2) { // 两个小数位数相同
            result = n1 + n2;
          } else if (t1 > t2) { // o1 小数位 大于 o2
            result = n1 + n2 * (t1 / t2);
          } else { // o1 小数位 小于 o2
            result = n1 * (t2 / t1) + n2;
          }
          return result / max;
        case 'subtract':
          if (t1 === t2) {
            result = n1 - n2;
          } else if (t1 > t2) {
            result = n1 - n2 * (t1 / t2);
          } else {
            result = n1 * (t2 / t1) - n2;
          }
          return result / max;
        case 'multiply':
          result = (n1 * n2) / (t1 * t2);
          return result;
        case 'divide':
          result = (n1 / n2) * (t2 / t1);
          return result;
      }
    },
    add: function(a, b, digits) {
      return this.operation(a, b, digits, 'add');
    },
    subtract: function(a, b, digits) {
      return this.operation(a, b, digits, 'subtract');

    },
    multiply: function(a, b, digits) {
      return this.operation(a, b, digits, 'multiply');

    },
    divide: function(a, b, digits) {
      return this.operation(a, b, digits, 'divide');
    }
  },

  isIos:function(){
    if(window.navigator.userAgent.toLowerCase().indexOf("iphone") > 0
      || window.navigator.userAgent.toLowerCase().indexOf("ios") >0){
      return true;
    }else{
      return false;
    }
  },
  isAndroid:function(){
    if(window.navigator.userAgent.toLowerCase().indexOf("android") > 0){
      return true;
    }else{
      return false;
    }
  },
               
   /*
    *   简单异常信息上报，包含标题、错误描述。
    */
    transmitGeneralError:function(title, content){
        var error = {
            "title" : title,
            "errorMsg" : content
        };

        this.transmitError(error);
    },

    /*
     *   详细异常信息上报，包含标题、错误描述、异常堆栈信息。
     */
    transmitDetailError:function(title, content, errorDetail){
        var error = {
            "title" : title,
            "errorMsg" : content,
            "errorInfo" : errorDetail
        };

        this.transmitError(error);
    },

    /*
     *   异常捕捉发送到统计后端 传送标题写死，内容为错误信息内容。
     */
   transmitError:function(paramMes){
   var parm = {};
   parm["funcNo"]= "81015";
   parm["errorMessage"]= paramMes;
   var result = callMessageNative(parm);
   },

   addMask:function(){
     var body=document.body;
     var mask=document.createElement('div');
     mask.id='backgroundmask';
     mask.className='rating-bg-transparent';
     body.appendChild(mask);
   },
   removeMask:function(){
     var mask=document.getElementById('backgroundmask');
     if(mask){
         mask.remove();
     }
   },
   //判断是否为字符串类型
   isString:function(val){
       return (typeof val==='string') && val.constructor===String;
   },
   //判断是否为对象类型
   isObject:function(val){
       return (typeof val==='object') && val.constructor===Object;
   },  
   /*
   *  功能：数组去重
   *  入参：需要去重的数组
   *  返回：去重后的数组
   */
   arrayUnique:function(arr){
      var res = [];      //存放数组结果集
      var json = {};     //对象属性标识数组对象是否存在重复元素
      for(var i = 0,len = arr.length; i < len; i++){
        if(!json[arr[i]]){
            json[arr[i]] = 1;
        }else{
            this.arrayRemove(res,arr[i]);
        }
        res.push(arr[i]);
      }
      return res;
   },
   /*
   *  删除数组指定元素
   *  入参:arr 传入的数组  val:要删除的值
   *  返回:删除元素后的数组
   */
   arrayRemove:function(arr,val){
       var index = -1;   //获取删除元素所在的索引位置
       for(var i = 0,len = arr.length; i < len; i++){
           if(arr[i] == val){
               index = i;
           }
       }
       arr.splice(index,1);
       return arr;
   },
   //银行卡列表
   appBankList:[
     {
      bankName:'招商银行',
      bankRealNo:'007',
      quotaVal:'单笔，单日限额200万元',
      discountVal:'申购，定投，转换6折',
      isSupportApp:true,
      bankStatus:'快捷'
     },
     {
      bankName:'工商银行',
      bankRealNo:'002',
      quotaVal:'单笔，单日限额30万元',
      discountVal:'申购，定投，转换4折',
      isSupportApp:true,
      bankStatus:'快捷'
     },
     {
      bankName:'农业银行',
      bankRealNo:'003',
      quotaVal:'单笔，单日限额200万元',
      discountVal:'申购，转换7折，定投4折',
      isSupportApp:true,
      bankStatus:'快捷'
     },
     {
      bankName:'建设银行',
      bankRealNo:'005',
      quotaVal:'单笔，单日限额50万元',
      discountVal:'申购，定投，转换4折',
      isSupportApp:true,
      bankStatus:'快捷'
     },
     {
      bankName:'中国银行',
      bankRealNo:'004',
      quotaVal:'单笔，单日限额50万元',
      discountVal:'申购，定投，转换6折',
      isSupportApp:true,
      bankStatus:'快捷'
     },
     {
      bankName:'浦发银行',
      bankRealNo:'009',
      quotaVal:'单笔，单日限额100万元',
      discountVal:'申购，定投，转换4折',
      isSupportApp:true,
      bankStatus:'快捷'
     },
     {
      bankName:'光大银行',
      bankRealNo:'012',
      quotaVal:'单笔，单日限额5万元',
      discountVal:'申购，定投，转换6折',
      isSupportApp:true,
      bankStatus:'银联快捷'
     },
     {
      bankName:'中信银行',
      bankRealNo:'008',
      quotaVal:'单笔5万元，单日限额20万元',
      discountVal:'申购，定投，转换6折',
      isSupportApp:true,
      bankStatus:'银联快捷'
     },
     {
      bankName:'兴业银行',
      bankRealNo:'011',
      quotaVal:'单笔，单日限额5万元',
      discountVal:'申购，定投，转换6折',
      isSupportApp:true,
      bankStatus:'银联快捷'
     },
     {
      bankName:'北京农商银行',
      bankRealNo:'019',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'北京银行',
      bankRealNo:'016',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'渤海银行',
      bankRealNo:'077',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'东莞银行',
      bankRealNo:'001',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'广发银行',
      bankRealNo:'060',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'杭州银行',
      bankRealNo:'021',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'华夏银行',
      bankRealNo:'017',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'江苏银行',
      bankRealNo:'076',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'交通银行',
      bankRealNo:'006',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'民生银行',
      bankRealNo:'014',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'南京银行',
      bankRealNo:'048',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'宁波银行',
      bankRealNo:'038',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'平安银行',
      bankRealNo:'601',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'上海农商银行',
      bankRealNo:'072',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'上海银行',
      bankRealNo:'401',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'深圳农商银行',
      bankRealNo:'080',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'天津银行',
      bankRealNo:'032',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'温州银行',
      bankRealNo:'075',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'邮政储蓄银行',
      bankRealNo:'015',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'浙江稠州商业银行',
      bankRealNo:'082',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'浙江民泰商业银行',
      bankRealNo:'081',
      quotaVal:'',
      discountVal:''    
     },
     {
      bankName:'浙商银行',
      bankRealNo:'074',
      quotaVal:'',
      discountVal:''    
     }
   ],
  //版本号判断，clientVerion：支持的版本号，newVerion：客户端版本号  支持版本格式：2，（一位），2.0（两位），2.0,1（三位）
    versionIsSupport:function(clientVerion,newVerion){
        if(clientVerion===newVerion){
            return true;
        }
        var clientList=clientVerion.split('.');
        var newList=newVerion.split('.');
        if(parseFloat(newList[0])>parseFloat(clientList[0])){
             return true
        }else if(parseFloat(newList[0])===parseFloat(clientList[0]) && parseFloat(newList[1])>parseFloat(clientList[1])){
             return true
        }else if(parseFloat(newList[0])===parseFloat(clientList[0]) && parseFloat(newList[1])===parseFloat(clientList[1]) && parseFloat(newList[2])>parseFloat(clientList[2])){
             return true
        }else{
            return false;
        }
        return false;
    }
};
               
//CMF自定义事件引擎，用于自定义事件的监听、触发、移除
cmf.EventEngine = cmf.EventEngine || {
  handlers: {}, //函数处理器数组
  addEventListener: function(eventName, handler) { //添加一个事件处理器
    if (typeof this.handlers[eventName] == "undefined") {
      this.handlers[eventName] = [];
    }
    this.handlers[eventName].push(handler);
  },
  fireEventListener: function(event) { //触发事件
    if (!event.target) {
      event.target = this;
    }
    if (this.handlers[event.eventName] instanceof Array) {
      var handlers = this.handlers[event.eventName];
      for (var i = 0, len = handlers.length; i < len; i++) {
        handlers[i](event);
      }
    }
  },
  removeEventListener: function(eventName, handler) { //删除事件处理器
    if (this.handlers[eventName] instanceof Array) {
      var handlers = this.handlers[eventName];
      for (var i = 0, len = handlers.length; i < len; i++) {
        if (handlers[i] === handler) {
          break;
        }
      }
      handlers.splice(i, 1); //删除指定的handler处理器
    }
  },
  removeEventListenerAll: function() {
    this.handlers = {};
  },
  removeEventListenerToEventName: function(eventName) {
    this.handlers[eventName] = undefined;
  }
};

//全局配置类
cmf.Config = cmf.Config || {
    isUser99ClickLog : true
};

/**
 * 统一处理支付密码，包括密码框样式和对应安全键盘的处理
 */
(function(window, angular, undefined) {
  'use strict';
  var cmfPayPassWordModule = angular.module('cmf_PayPassWord', []);
  cmfPayPassWordModule.directive('paypasswordTip', function() {
    return {
      //|<span class="last_q" ng-bind="bankCardNo"></span>
      restrict: 'E',
      template: '<div class="popup_bg ng-hide" ng-show="showPassword" touch-prevent></div>\
                <div class="popup_fund ng-hide popupScroll" ng-show="showPassword" touch-prevent>\
                    <div class="popup_cont">\
                        <div class="popup_title">{{fundNm}}</div>\
                        <div class="jine">{{redeemAmt}}</div>\
                        <div class="bank_detail">\
                            <span class="aboutBnk" ng-bind="realBankName"></span>\
                        </div>\
                        <div class="pwdInput buy_PwdInput" id="tradePage">\
                           <input type="password" id="pwdIptPay" nextbutton="confirm();" paypassword-native ng-model="payPassword" ng-click="keyboardUp(\'tradePage\',\'pwdIptPay\');" class="pwd_input" maxLength="16" placeholder="请输入支付密码" ng-class="{true:\'input_prevent\',false:\'\'}[isTradeing]" clear-input inputblur popup-scroll/>\
                        </div>\
                    </div>\
                    <div class="sureStop">\
                      <a class="err_btn1" ng-click="showPassword=false">取消</a>\
                        <a class="stop zqbDeposit" ng-class="{true:\'oth_actived\',false:\'\'}[isTradeing]" ng-click="confirm();">{{tradeName}}</a>\
                    </div>\
                </div>',
      scope: {
        showPassword: '=',
        payPassword: '=',
        fundNm: '@',
        redeemAmt: '@',
        realBankName: '@',
        bankCardNo: '@',
        trade: '&',
        tradeName: '@',
        isTradeing:'='
      },
      link: function(scope, ele, attr) {
        scope.payPassword = '';
        scope.$watch('showPassword',function(data){
            if(data===true){
                setTimeout(function(){
                    document.getElementById('pwdIptPay').click();
                    document.getElementById('pwdIptPay').focus();
                },50);
            }
        });
        scope.confirm = function() {
          document.addEventListener('touchstart',handler,false);
          cmf.NativeViewUtil.keyboardDownForNative('0');
        if (!scope.payPassword || (scope.payPassword.length < 6 || scope.payPassword.length > 16)) {
            scope.payPassword = ''; //清空支付密码
            cmf.NativeViewUtil.showAlert('支付密码格式不正确,请重新输入');
            document.removeEventListener('touchstart',handler,false);
          return;
        }
          //cmf.NativeViewUtil.showLoadingView(true);
          scope.trade();
        };
      }
    }
  });
  cmfPayPassWordModule.directive('paypasswordNative', ['$parse', function($parse) {
    return {
      restrict: 'A',
      require: '^?ngModel',
      link: function(scope, ele, attr, ngModel) {
        //移除键盘监听
        function removeEventListener(){
          cmf.EventEngine.removeEventListenerToEventName(cmfEvent_KeyboardDeleteChar);
          cmf.EventEngine.removeEventListenerToEventName(cmfEvent_KeyboardInputing);
          cmf.EventEngine.removeEventListenerToEventName(cmfEvent_KeyboardComfirmButtonClick);
        }

        //添加键盘监听
        function addEventListener(){
          //响应原生键盘 回退按钮
          cmf.EventEngine.addEventListener(cmfEvent_KeyboardDeleteChar, function(event) {
            //        alert("cmfEvent_KeyboardDeleteChar:" + JSON.stringify(event));
            //var passwordVal = scope.payPassword; document.querySelector('#'+event.message.pageId).querySelector('#'+event.message.eleId)
            var passwordVal = ngModel.$viewValue;
            var lastIndex = passwordVal;
            var password = ele[0];
            var selection = password.selectionStart;
            if (password.selectionStart === 0) {
              return;
            } else if (password.selectionStart === passwordVal.length) {
              passwordVal = passwordVal.substring(0, password.selectionStart - 1);
            } else {
              passwordVal = passwordVal.substring(0, password.selectionStart - 1) + passwordVal.substring(password.selectionStart, passwordVal.length);
            }
            //scope.payPassword = passwordVal;
            ngModel.$setViewValue(passwordVal);
            ele.val(passwordVal);
            //手动刷新
            if (!scope.$$phase)
              scope.$apply();
            if (password.selectionStart !== 0 && password.selectionStart !== lastIndex.length) {
              password.selectionStart = selection - 1;
              password.selectionEnd = selection - 1;
            }
            //TODO:在此添加删除逻辑
          });

          //响应原生键盘普通按钮
          cmf.EventEngine.addEventListener(cmfEvent_KeyboardInputing, function(event) {
            //if(!scope.payPassword) scope.payPassword='';
            // alert("cmfEvent_KeyboardInputing:" + JSON.stringify(event));
            // var passwordVal = scope.payPassword;  document.querySelector('#'+event.message.pageId).querySelector('#'+event.message.eleId)
            var passwordVal = ngModel.$viewValue || '';
            var lastIndex = passwordVal;
            var password = ele[0];
            var selection = password.selectionStart;
            if (password.selectionStart === 0) {
              passwordVal = event.message.keyCode + (ngModel.$viewValue || '');
            } else if (password.selectionStart === passwordVal.length) {
              passwordVal += event.message.keyCode;
            } else {
              passwordVal = passwordVal.substring(0, password.selectionStart) + event.message.keyCode + passwordVal.substring(password.selectionStart, passwordVal.length);
            }
            //scope.payPassword  = passwordVal;
            //var dataType = ele[0].dataset.type;
            //var pwdLength;
            //if(dataType == 'loginPassword'){    //登录密码输入框
            //  pwdLength = 8;
            //}else if(dataType == 'moneyInput'){ //金额输入框
            //  //验证：整数位最大为10位 小数位2位
            //  if(passwordVal.indexOf('.') == -1){
            //    pwdLength = 10;
            //  }else if(passwordVal.indexOf('.') != -1){
            //    pwdLength = 13;
            //  }
            //}else if(dataType == 'codeInput'){    //验证码输入框
            //  pwdLength = 6;
            //}else{        //支付密码输入框
            //  pwdLength = 16;
            //}
            if (passwordVal.length > 16) {
              return;
            }
            //if(dataType == 'loginPassword' || dataType == 'codeInput' || dataType == 'moneyInput'){
            //  if(!Number(passwordVal) || isNaN(passwordVal)){
            //    return;
            //  }
            //}

            //if(dataType == 'moneyInput'){
            //  if(passwordVal.indexOf('.') != -1){
            //    var temp = passwordVal.split('.');
            //    if(temp[1].length > 2){
            //      return;
            //    }
            //  }
            //}
            ngModel.$setViewValue(passwordVal);
            ele.val(passwordVal);
            //手动刷新
            if (!scope.$$phase)
              scope.$apply();
            password.selectionStart = selection + 1;
            password.selectionEnd = selection + 1;
            //TODO:在此添加正在输入的数据更新与按钮状态更新
          });

          cmf.EventEngine.addEventListener(cmfEvent_KeyboardComfirmButtonClick, function() {
            ele[0].blur();
            if (attr.nextbutton) {
              $parse(attr.nextbutton)(scope); //解析angular表达式并传入上下文 执行表达式
            }
          });

        }

        removeEventListener();
        addEventListener();
        ele.bind('click', function() {
          //var dataKey = ele[0].dataset.keyboard;
          var dataType = ele[0].dataset.type;
          if (dataType == 'loginPassword') {
            cmf.NativeViewUtil.keyboardUpForNative('abb', 'acc', '10'); //招商数字键盘
          } else {
            cmf.NativeViewUtil.keyboardUpForNative('abb', 'acc', '12'); //招商英文键盘
          }
        });
        ele.bind('blur', function() {
          cmf.NativeViewUtil.keyboardDownForNative('0');
        });

      }
    };
  }]);
  cmfPayPassWordModule.directive('resetPassword', function($timeout) {
    //页面有多个需要安全键盘输入框时处理
    return {
      restrict: 'E',
      template: '<div class="loginInput bgWhite ">\
            <input type="password" class="userInput  newPayPassword borderline" ng-focus="fixInputFocus()" ng-model="payPassword" placeholder="请输入{{typeResetVal}}密码" id="newPayPassword" ng-click="keyUpforCtr(\'newPayPassword\')"   clear-input maxlength="16"/>\
          </div>\
          <div class="loginInput bgWhite">\
            <input type="password" class="userInput confirmNPassword" ng-focus="fixInputFocus()" ng-model="comfirePayPassword" placeholder="请再次输入{{typeResetVal}}密码" id="confirmNPassword"  ng-click="keyUpforCtr(\'confirmNPassword\')"  clear-input maxlength="16"/>\
          </div>',
      scope: {
        payPassword: '=password',
        comfirePayPassword: '=comfirePassword',
        typeVal: '@'
      },
      link: function($scope, ele, attr) {

        //---------- 解决IOS重新获得input框焦点时光标位置不对（在左边）的bug ---
        //-- 需要在 input元素上绑定ng-focus事件
        $scope.fixInputFocus = function(){
          if(cmf.Util.isIos()){
            $timeout(function() {
              document.activeElement.setSelectionRange(1000,1000);
            }, 10);
          }
        }
        //----------

        var maxLength = 0;
        if ($scope.typeVal === 'login') {
          maxLength = 8;
          $scope.typeResetVal = '登录';
        } else if ($scope.typeVal === 'pay') {
          maxLength = 16;
          $scope.typeResetVal = '支付';
        }
        cmf.EventEngine.removeEventListenerToEventName(cmfEvent_KeyboardDeleteChar);
        cmf.EventEngine.removeEventListenerToEventName(cmfEvent_KeyboardInputing);
        cmf.EventEngine.removeEventListenerToEventName(cmfEvent_KeyboardComfirmButtonClick);
        //响应原生键盘 回退按钮
        cmf.EventEngine.addEventListener(cmfEvent_KeyboardDeleteChar, function(event) {
          //        alert("cmfEvent_KeyboardDeleteChar:" + JSON.stringify(event));
          //var passwordVal = scope.payPassword; document.querySelector('#'+event.message.pageId).querySelector('#'+event.message.eleId)
          var passwordVal = $scope[$scope.payVal];
          var lastIndex = passwordVal;
          var password = $scope.inputSelect;
          password.selectionStart = password.selectionStart;
          password.selectionEnd = password.selectionEnd;
          var selection = password.selectionStart;
          if (password.selectionStart === 0) {
            return;
          } else if (password.selectionStart === passwordVal.length) {
            passwordVal = passwordVal.substring(0, password.selectionStart - 1);
          } else {
            passwordVal = passwordVal.substring(0, password.selectionStart - 1) + passwordVal.substring(password.selectionStart, passwordVal.length);
          }
          //scope.payPassword = passwordVal;
          // ngModel.$setViewValue(passwordVal);
          // ele.val(passwordVal);
          $scope[$scope.payVal] = passwordVal;
          //手动刷新
          if (!$scope.$$phase)
            $scope.$apply();
          if (password.selectionStart !== 0 && password.selectionStart !== lastIndex.length) {
            password.selectionStart = selection - 1;
            password.selectionEnd = selection - 1;
          }
          //TODO:在此添加删除逻辑
        });
        //响应原生键盘 普通按钮
        cmf.EventEngine.addEventListener(cmfEvent_KeyboardInputing, function(event) {
          //if(!scope.payPassword) scope.payPassword='';
          // alert("cmfEvent_KeyboardInputing:" + JSON.stringify(event));
          // var passwordVal = scope.payPassword;  document.querySelector('#'+event.message.pageId).querySelector('#'+event.message.eleId)
          var passwordVal = $scope[$scope.payVal] || '';
          var lastIndex = passwordVal;
          var password = $scope.inputSelect;
          password.selectionStart = password.selectionStart;
          password.selectionEnd = password.selectionEnd;
          var selection = password.selectionStart;
          if (password.selectionStart === 0) {
            passwordVal = event.message.keyCode + ($scope[$scope.payVal] || '');
          } else if (password.selectionStart === passwordVal.length) {
            passwordVal += event.message.keyCode;
          } else {
            passwordVal = passwordVal.substring(0, password.selectionStart) + event.message.keyCode + passwordVal.substring(password.selectionStart, passwordVal.length);
          }
          //scope.payPassword  = passwordVal;
          // ngModel.$setViewValue(passwordVal);
          // ele.val(passwordVal);
          if (passwordVal.length > maxLength) {
            return;
          }
          $scope[$scope.payVal] = passwordVal;
          //手动刷新
          if (!$scope.$$phase)
            $scope.$apply();
          password.selectionStart = selection + 1;
          password.selectionEnd = selection + 1;
          //TODO:在此添加正在输入的数据更新与按钮状态更新
        });
        cmf.EventEngine.addEventListener(cmfEvent_KeyboardComfirmButtonClick, function(event) {
          if (event.message.keyCode === '-3') {
            $scope.keyBoardShow = false;
            document.removeEventListener("touchend", docTouchend, false);
          }
        });
        var payPass = document.getElementById('newPayPassword');
        var payPassCof = document.getElementById('confirmNPassword');
        $scope.keyBoardShow = false;
        $scope.inputSelect = '';
        $scope.payVal = '';
        $scope.keyUpforCtr = function(id) {

           if(window.iBrowser.android){
            $scope.keyBoardShow = false;
           }
          if ($scope.keyBoardShow === false) {

            $scope.keyBoardShow = true;
            objBlur(document);
            //区分登录键盘和支付键盘
            if ($scope.typeVal === 'login') {
              cmf.NativeViewUtil.keyboardUpForNative('abb', 'acc', '10'); //招商数字键盘
            } else {
              cmf.NativeViewUtil.keyboardUpForNative('abb', 'acc', '12'); //招商全键盘
            }
          }
          if (id === 'newPayPassword' && ($scope.payVal === '' || $scope.payVal === 'comfirePayPassword')) {
            payPass.selectionStart = $scope.payPassword.length;
            payPass.selectionEnd = $scope.payPassword.length;
            $scope.inputSelect = payPass;
            $scope.payVal = 'payPassword';
          } else if (id === 'confirmNPassword' && ($scope.payVal === '' || $scope.payVal === 'payPassword')) {
            payPassCof.selectionStart = $scope.comfirePayPassword.length;
            payPassCof.selectionEnd = $scope.comfirePayPassword.length;
            $scope.inputSelect = payPassCof;
            $scope.payVal = 'comfirePayPassword';
          }
        };

        function docTouchend(event) {
          if (event.target != payPass && event.target != payPassCof && event.target.className.indexOf("clearIcon") == -1) {
            setTimeout(function() {
              payPass.blur();
              payPassCof.blur();
              cmf.NativeViewUtil.keyboardDownForNative('0');
              $scope.keyBoardShow = false;
              document.removeEventListener("touchend", docTouchend, false);
            }, 0);
          }
        }

        function objBlur(document) {
          document.addEventListener("touchend", docTouchend, false);
        }
      }
    };
  });
})(window, window.angular);


/**
 * UI
 */
(function(window, angular, undefined) {

  var native = angular.module("nativeDirective",[]);
  native.directive("nativeMask",function(){

    return {

      restrict:"A",
      scope:{
        "show":"=ngShow",
        "alpha":"@nativeMask"
      },
      controller: function($scope,$element,$attrs){
        if($scope.show){
          cmf.NativeViewUtil.showBackground($scope.alpha);
        }else{
          cmf.NativeViewUtil.hideBackground();
        }
      }
    };
  });

})(window, window.angular);
if(cmf.route.isDebug===false){
window.console.log=function(val){
};
}
